﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using Microsoft.Reputation.Services;

namespace Microsoft.Reputation.Tests.FrontEndCommon
{
    public class TelemetryHelper
    {
        private static Random rndm = new Random((int)DateTime.Now.Ticks);

        public static uint GetUint(string countType)
        {
            return GetUint(countType, int.MinValue, int.MaxValue);
        }

        public static uint GetUint(string countType, int min, int max)
        {
            switch (countType.ToLower())
            {
                case "valid":
                    return (uint)rndm.Next(min, max);
                case "zero":
                    return 0;
                case "max":
                    return uint.MaxValue;
                default:
                    Console.WriteLine("Input type {0} to GetUint came to default condition. Converting the String input to Uint.", countType);
                    return uint.Parse(countType);
            }
        }

        public static string GetUrl(string urlType)
        {
            switch (urlType.ToLower())
            {
                case "valid":
                    string url = Path.GetRandomFileName();
                    url = url + url + url + url + url; // As per bug 1326, the average size of a URL is 59 characters. Path.GetRandomFileName gives a string of size 12. So making urls of length 68, which is close to the average length we expect.
                    string result = "www." + url + ".com";
                    return result;
                case "null":
                    return null;
                case "empty":
                    return String.Empty;
                default:
                    Console.WriteLine("Input type {0} to GetUrl came to default condition. Returning the String itself.", urlType);
                    return urlType;
            }
        }

        public static uint GetCategoryId(string categoryType)
        {
            //TODO -> Once the Category Validation is finalized in the Dev code, modify this class. Read the CategoryID's from http://sharepoint/sites/reputation/Shared%20Documents/Projects/PM/MRS%20-%20Taxonomy%20-%20Category%20Mapping.xlsx
            switch (categoryType.ToLower())
            {
                case "valid":
                    return 29360148; //Alcohol Category
                case "invalid":
                    return 10000000; // TODO this needs to be modified to surely pickup an invalid CategoryId.
                case "zero":
                    return 0;
                default:
                    Console.WriteLine("Input type {0} to GetCategoryId came to default condition. Converting the String input to Uint.", categoryType);
                    return uint.Parse(categoryType);
            }
        }

        public static DateTime GetDateTime(string dateType)
        {
            switch (dateType)
            {
                case "Valid":
                    return DateTime.Now;
                case "Min":
                    return DateTime.MinValue;
                case "Max":
                    return DateTime.MaxValue;
                case "Invalid":
                    return DateTime.Now; // TODO -> need to figure this out.
                default:
                    throw new ArgumentException("Invalid parameter/input '" + dateType + "'. The valid inputs for GetDateTime are 'Valid', 'InValid', 'Max' and 'Min'.");
            }
        }

        public static Microsoft.Reputation.Services.Action GetAction(string actionType)
        {
            switch (actionType.ToLower())
            {
                case "valid":
                    return Microsoft.Reputation.Services.Action.Allow;
                case "invalid":
                    return Microsoft.Reputation.Services.Action.SoftBlock;
                default:
                    throw new ArgumentException("Invalid parameter/input '" + actionType + "'. The valid inputs for GetAction are 'Valid' and 'InValid'.");
            }
        }

        public static string GetIPAddress(string ipAddressType)
        {
            switch(ipAddressType.ToLower())
            {
                case "invalid":
                    return "0.0.0.0"; 
                default:
                    return GetUrl(ipAddressType); // Calling GetUrl until IPAddress is validated in the Dev Code.
            }
        }

        public static Guid GetGUID(string guidType)
        {
            switch (guidType.ToLower())
            {
                case "valid":
                    return Guid.NewGuid();
                case "invalid":
                    return Guid.Empty; // Need to update this once Dev code validation updates.
                case "empty":
                    return Guid.Empty;
                default:
                    throw new ArgumentException("Invalid parameter/input '" + guidType + "'. The valid inputs for GetGUID are 'Valid', 'InValid' and 'Empty'.");
            }
        }

        public static T[] GetList<T>(Func<T> GetValidObject, Func<T> GetSpecialObject, int size, int pos) // TODO: Need a better name for the function.
        {
            if (size < 0)
            {
                throw new ArgumentException("Size of the SampleUrl list cannot be set to 0 or negative.", "size");
            }
            if (size == 0)
            {
                DisplayWarning("The size specified is 0, so an Empty list will be created.");
            }
            if (pos >= size)
            {
                DisplayWarning("The position specified is greater than size-1, so the 'Special' object will not be added.");
            }
            if (pos < 0)
            {
                throw new ArgumentException("Position of the SampleUrl object cannot be negative, it has to be 0 or greater", "pos");
            }

            T[] resultObj = new T[size];

            for (int i = 0; i < size; i++)
            {
                resultObj[i] = i == pos ? GetSpecialObject() : GetValidObject();
            }

            return resultObj;
        }

        public static void DisplayWarning(string warning)
        {
            ConsoleColor temp = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("WARNING: {0}", warning);
            Console.ForegroundColor = temp;
        }
    }
}